package com.example.waterdispenserm2.mo.water;


import java.util.Arrays;

public class WaterDispenserProtocol {
        // 帧头定义
        private static final byte FRAME_HEADER = (byte) 0xF0;

        // 计算校验码
        public static byte calculateChecksum(byte[] data) {
            byte checksum = (byte) 0xFF;
            for (byte b : data) {
                checksum ^= b;
            }
            return checksum;
        }

        // 构建指令帧
        public static byte[] buildCommandFrame(byte command, byte[] params) {
            // 长度 = 内容长度 + 2 (长度字节和校验字节)
            int length = params.length + 2;
            byte[] frame = new byte[length + 1]; // 加1是因为帧头

            // 填充数据
            frame[0] = FRAME_HEADER;
            frame[1] = (byte) (length - 1); // 长度 = 总字节数 - 2
            frame[2] = command;

            System.arraycopy(params, 0, frame, 3, params.length);

            // 计算校验码 (从命令字节开始)
            byte[] content = Arrays.copyOfRange(frame, 2, frame.length - 1);
            frame[frame.length - 1] = calculateChecksum(content);

            return frame;
        }

        // 解析温度值
        public static float parseTemperature(byte value) {
            return value & 0xFF; // 无符号转换
        }

        // 解析水量值
        public static int parseWaterVolume(byte high, byte low) {
            return ((high & 0xFF) << 8) | (low & 0xFF);
        }

        // 构建出水指令
        public static byte[] buildDispenseCommand(int targetTemp, int flowRate, int volume, boolean continuous) {
            byte[] params = new byte[5];
            params[0] = (byte) targetTemp;          // 目标温度
            params[1] = (byte) (flowRate / 10);     // 流速/10
            params[2] = (byte) (volume >> 8);       // 水量高字节
            params[3] = (byte) (volume & 0xFF);     // 水量低字节
            params[4] = continuous ? (byte) 0x01 : (byte) 0x00; // 出水模式

            return buildCommandFrame((byte) 0xA1, params);
        }

        // 构建查询指令
        public static byte[] buildQueryCommand(int queryType) {
            byte[] params = new byte[]{(byte) queryType};
            return buildCommandFrame((byte) 0xA3, params);
        }



    // 解析累计流量回复 (B5指令)
    public static int parseWaterVolumeData(byte[] data) {
        if (data.length < 4 || data[0] != FRAME_HEADER || data[2] != (byte) 0xB5)
            return -1;

        // B5指令格式: F0 03 B5 [高字节] [低字节] [校验]
        int high = data[3] & 0xFF;
        int low = data[4] & 0xFF;
        return (high << 8) | low;
    }

    // 构建累计流量查询指令 (A5)
    public static byte[] buildWaterVolumeQuery() {
        return buildCommandFrame((byte) 0xA5, new byte[]{0x00});
    }

    // 解析瞬时流量回复 (B4指令)
    public static int parseFlowRateData(byte[] data) {
        if (data.length < 3 || data[0] != FRAME_HEADER || data[2] != (byte) 0xB4)
            return -1;

        return data[3] & 0xFF; // 瞬时流量值
    }


    // 解析温度数据 (B3指令)
    public static float parseTemperatureData(byte[] data) {
        /**
         * B3指令格式 (检测值回复):
         * 帧头(1) | 长度(1) | 命令字(B3)(1) | 参数1(1) | 参数2高(1) | 参数2低(1) | 校验(1)
         * 总长度: 7字节
         *
         * 参数1: 同A3定义 (00:热水NTC实时值)
         * 参数2: 2字节的温度值 (高位在前)
         *
         * 实际温度 = (参数2高 << 8 | 参数2低) / 10.0
         */
        if (data.length < 7 || data[0] != FRAME_HEADER || data[2] != (byte) 0xB3)
            return -1000; // 特殊值表示无效温度

        // 检查是否是温度查询回复 (参数1=00)
        if (data[3] != 0x00) {
            return -1000;
        }

        // 解析温度值
        int high = data[4] & 0xFF;
        int low = data[5] & 0xFF;
        int rawTemp = (high << 8) | low;

        // 检查温度符号 (高位为00表示正值，01表示负值)
        boolean isNegative = (high & 0x80) != 0; // 检查最高位符号位
        float temperature = rawTemp / 10.0f;

        return isNegative ? -temperature : temperature;
    }


    // 构建瞬时流量查询指令 (A4)
    public static byte[] buildFlowRateQuery() {
        return buildCommandFrame((byte) 0xA4, new byte[]{0x00});
    }

    // 解析状态数据 (B8指令) 增加水量状态
    public static DispenserStatus parseStatusData(byte[] data) {
        if (data.length < 7 || data[0] != FRAME_HEADER || data[2] != (byte) 0xB8)
            return null;

        DispenserStatus status = new DispenserStatus();
        status.mode = data[3]; // 工作模式
        status.temperature = parseTemperature(data[4]); // 当前温度
        status.waterStatus = data[5]; // 水量状态 (01:上一次出水完成时有水, 02:缺水)
        status.flowStatus = data[6]; // 水流状态 (01:有水, 02:无水)
        return status;
    }


        public static class DispenserStatus {
            public int mode;        // 工作模式 (01待机, 02出水)
            public float temperature; // 当前温度
            public int waterStatus; // 水量状态 (01有水, 02无水)
            public int flowStatus;  // 水流状态 (01有水, 02无水)
        }

}
